#ifndef CONCISEUI_BASE_SYNCSLOT_H_
#define CONCISEUI_BASE_SYNCSLOT_H_
#pragma once

#include <assert.h>
#include <vector>
#include "../concise-ui.h"
#include "SignalTarget.h"

namespace base {

class CallBack0
{
public:
	typedef void (SignalTarget::*SignalFunc)();

	struct SignalSlot
	{
		SignalTarget*	signal_target;
		SignalFunc		signal_func;
	};

	CallBack0() {}
	~CallBack0() {}

	template <typename TARGET, typename SIGNAL_FUNC>
	void Connect(TARGET* signal_target, SIGNAL_FUNC signal_func)
	{
		signal_slot_.signal_target = reinterpret_cast<SignalTarget*>(signal_target);
#pragma warning( push )
#pragma warning( disable : 4407 )
		signal_slot_.signal_func = static_cast<SignalFunc>(signal_func);
#pragma warning( pop )
	}

	void Emit()
	{
		(signal_slot_.signal_target->*(signal_slot_.signal_func))();
	}

private:
	SignalSlot signal_slot_;
};

class Signal0 : public CallBack0
{
public:
	typedef std::vector<SignalSlot> SignalSlots;

	Signal0() {}
	~Signal0() {}

	template <typename TARGET, typename SIGNAL_FUNC>
	void Connect(TARGET* signal_target, SIGNAL_FUNC signal_func)
	{
		SignalSlot signal_slot;
		signal_slot.signal_target = reinterpret_cast<SignalTarget*>(signal_target);
#pragma warning( push )
#pragma warning( disable : 4407 )
		signal_slot.signal_func = static_cast<SignalFunc>(signal_func);
#pragma warning( pop )
		signal_slots_.push_back(signal_slot);
	}

	template <typename TARGET>
	void DisConnect(TARGET* signal_target)
	{
		SignalTarget* signal_target = reinterpret_cast<SignalTarget*>(signal_target);
		for(SignalSlots::const_iterator iter = signal_slots_.begin(); iter != signal_slots_.end();)
		{
			if(iter->signal_target == signal_target)
			{
				signal_slots_.erase(iter);
				continue;
			}

			iter++
		}
	}

	void Emit()
	{
		for(SignalSlots::const_iterator iter = signal_slots_.begin(); iter != signal_slots_.end(); iter++)
		{
			(iter->signal_target->*(iter->signal_func))();
		}
	}

private:
	SignalSlots	signal_slots_;
};

} // namespace base

#endif // CONCISEUI_BASE_SYNCSLOT_H_